package com.fingard.dsp.bank.directbank.qlb03;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import static com.fingard.text.StringHelper.trimEndFileSp;

/**
 *
 * Created by F on 2019/02/26.
 */
public class QLB03BatPayRec extends QLB03Base implements IBatPayRec {

    private static final String INSERTSEQ = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
    private static final String SELECTSEQ = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=?;";

    /**
     * 批量代付提交
     *
     * @param p_req1988
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        //返回ATS的对象
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        Connection conn= FGBiz.getLocalDbConn();
        try{
            //拼接请求报文头
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            QLB03Header header=new QLB03Header();
            header.tr_code="300002";
            header.req_no = p_req1988.reqBatchNO;
            header.file_flag="1";
            writeCommonHeader(xmlTextWriter,header);
            xmlTextWriter.writeEndElement();
            //拼接请求报文体
            XElement body = new XElement("body","");
            body.addChild(new XElement("pay_acno",p_req1988.ownAct));//付款账号
            body.addChild(new XElement("pay_cur_code",convertCurToBank(p_req1988.ownCur)));//付款币种
            body.addChild(new XElement("pay_acname",p_req1988.ownActName));//付款户名
            body.addChild(new XElement("pay_accaddr",p_req1988.ownAreaName));//付款人地址
            body.addChild(new XElement("as_flag","0"));//是否使用账簿号 0：不需要 1：需
            body.addChild(new XElement("as_acno",""));//账簿号
            body.addChild(new XElement("as_acname",""));//账簿名称
            body.addChild(new XElement("vir_acno",""));//虚账号
            body.addChild(new XElement("vir_acname",""));//虚账号名称
            body.addChild(new XElement("supply_item","0001"));//项目编号 0001代发工资
            body.addChild(new XElement("batch_no",p_req1988.reqBatchNO));//批次号
            body.addChild(new XElement("count",p_req1988.totalNum));//总笔数
            body.addChild(new XElement("amt",p_req1988.totalAmt));//总交易金额
            body.addChild(new XElement("purpose",""));//用途
            body.addChild(new XElement("postscript",p_req1988.useType));//附言
            body.addChild(new XElement("qry_auth",p_req1988.useType));//查看权限操作员
            //拼接批付数据到文件
            String fileName=p_req1988.reqBatchNO+".txt";
            String filePath=StringHelper.trimEnd(FGBiz.dspCenter.dspSet.dataDirPath, "/") + File.separator + p_req1988.reqHeader.bankCode
                    + File.separator + Format.Date8Format.format(new Date());
            if(!FileHelper.existFile(filePath)){
                FileHelper.mkdir(filePath);
            }
            int tmpCount=0;
            StringBuilder sb=new StringBuilder("acno|cur_code|acname|cardflag|amt|postscript|").append("\r\n");
            while(p_req1988.readRecord()){
                tmpCount++;
                //账号|币种|户名|卡折标志（0-卡  1-折）|金额|附言|
                sb.append(p_req1988.readedDetail.recAct).append("|").append(convertCurToBank(p_req1988.readedDetail.recCur)).append("|")
                    .append(p_req1988.readedDetail.recName).append("|").append(" ").append("|")
                    .append(p_req1988.readedDetail.payAmount).append("|").append(p_req1988.readedDetail.askNumber).append("|");
                if(tmpCount!=Integer.parseInt(p_req1988.totalNum)){
                    sb.append("\r\n");
                }
            }
            String fileNamePath=filePath + File.separator + fileName;
            FileHelper.writeFile(fileNamePath,sb);
            //上传文件到前置机目录
            if(FileHelper.existFile(fileNamePath)){
                int result = SmbFileUtil.smbUploading(fileNamePath, "", bankFront.bkTransFolder);
                if(result==-1){
                    retAts.respCode = "-1";
                    retAts.respInfo = "上传文件到前置机目录异常";
                    retAts.writeRetToATS();
                    return retAts;
                }
            }
            body.addChild(new XElement("file_name",fileName));//文件名
            body.addChild(new XElement("field_num","6"));//每条记录字段数
            if(tmpCount!=Integer.parseInt(p_req1988.totalNum)){
                retAts.respCode = "-1";
                retAts.respInfo = "写入数据异常";
                retAts.writeRetToATS();
                return retAts;
            }
            body.addChild(new XElement("record_num",p_req1988.totalNum));//文件内记录数
            xmlTextWriter.writeXElement(body);
            xmlTextWriter.writeEndDocument();
            //发送请求报文
            String[] bankResult = sendToBank(requestBody(xmlTextWriter.toXmlString()));
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader xmlSbReader = loadBankRespXmlReader(bankResult[1].substring(bankResult[1].indexOf("<ap>")), tmpSbMsg);
                if (xmlSbReader != null) {
                    String serial_no= xmlSbReader.getFirstText("/ap/head/serial_no");
                    String respCode = "0000".equals(xmlSbReader.getFirstText("/ap/head/ret_code"))?"0000":"others";
                    String respInfo = xmlSbReader.getFirstText("/ap/head/ret_info");
                    String errorInfo =xmlSbReader.getFirstText("/ap/head/ext_info");
                    retAts.respCode = "0";
                    retAts.respInfo = respInfo+"："+errorInfo;
                    retAts.reqSeqID = p_req1988.reqBatchNO;
                    retAts.payInfoCode = respCode;
                    retAts.transState = retAts.payInfoCode;
                    //记录批次号对应的银行支付流水号，供查询状态接口使用
                    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                    JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1988.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1988.reqBatchNO, serial_no});
                }else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            }else if(bankResult[0].equals(ConnState.FAIL)){
                retAts.respCode = "0";
                retAts.respInfo = bankResult[1];
                retAts.reqSeqID = p_req1988.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = bankResult[0];
            }
            else{
                retAts.respCode = "-1";
                retAts.respInfo = bankResult[1];
            }
        }catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            WriteBankLogLn("批量代发异常："+e);
            e.printStackTrace();
        }finally {
            conn.close();
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1988.reqBatchNO;
        }
        retAts.writeRetToATS();
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        // 返回ATS的对象
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        Connection conn=FGBiz.getLocalDbConn();
        try {
            //拼接请求报文头
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            QLB03Header header=new QLB03Header();
            header.tr_code="200201";
            header.req_no = p_req1998.reqBatchNO;
            header.file_flag="0";
            writeCommonHeader(xmlTextWriter,header);
            xmlTextWriter.writeEndElement();//
            //拼接请求报文体
            XElement body = new XElement("body","");
            body.addChild(new XElement("tr_acdt",DateHelper.convertD10toD8(p_req1998.bgnDate.substring(0,10))));//交易日期
            Map<String, Object> selMap=JDBCHelper.execQuerySingle(conn,SELECTSEQ,new Object[]{p_req1998.reqBatchNO});
            if(selMap.size()>0){
                body.addChild(new XElement("serial_no", selMap.get("BANKREQSEQID").toString()));//平台流水号
            }else {
                retAts.respCode ="-1";
                retAts.respInfo = "批次号"+p_req1998.reqBatchNO+"未匹配对应的平台流水号";
                retAts.writeBeforeDetail();
                retAts.writeAfterDetail();
                return retAts;
            }
            body.addChild(new XElement("batch_no",p_req1998.reqBatchNO));//批次号
            body.addChild(new XElement("cms_corp_no",bankFront.org));
            xmlTextWriter.writeXElement(body);
            xmlTextWriter.writeEndDocument();
            //发送请求报文
            String[] bankResult = sendToBank(requestBody(xmlTextWriter.toXmlString()));
            //测试
            //String[] bankResult=new String[]{"","<ap><head><tr_code>200201</tr_code><cms_corp_no></cms_corp_no><user_no></user_no><req_no>PH00000BLK</req_no><serial_no>13390649</serial_no><tr_acdt>20190304</tr_acdt><tr_time>161523</tr_time><succ_flag>0</succ_flag><ret_info>交易成功</ret_info><ret_code>0000</ret_code><ext_info></ext_info><reserved></reserved><file_flag>0</file_flag><org_code></org_code><total>1</total></head><body><serial_record>seqno|acno|cur_code|acname|card_flag|amt|summary|tr_acdt|tr_time|stat|err_msg|batch_no|1|86611724101421001270|01|捷瑞物流银企直连测试账户002|0|134.00|000009AA|20190304|142854|9||304142943200|</serial_record><total>1</total><record_num>1</record_num><field_num>12</field_num><fail_count>0</fail_count><fail_amt>0.00</fail_amt><succ_count>1</succ_count><succ_amt>134.00</succ_amt></body></ap>"};
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader xmlSbReader = loadBankRespXmlReader(bankResult[1].substring(bankResult[1].indexOf("<ap>")), tmpSbMsg);
                if (xmlSbReader != null) {
                    String succFlag= xmlSbReader.getFirstText("/ap/head/succ_flag");
                    String respCode = xmlSbReader.getFirstText("/ap/head/ret_code");
                    String respInfo = xmlSbReader.getFirstText("/ap/head/ret_info");
                    String errorInfo =xmlSbReader.getFirstText("/ap/head/ext_info");
                    String fileFlag= xmlSbReader.getFirstText("/ap/head/file_flag");
                    if ("0".equals(succFlag) && "0000".equals(respCode)) {//交易成功
                        String totalNum=xmlSbReader.getFirstText("/ap/body/record_num");//总数
                        String valueNum=xmlSbReader.getFirstText("/ap/body/field_num");//字段数
                        String serial_recode=xmlSbReader.getFirstText("/ap/body/serial_record");//字段域
                        if("0".equals(fileFlag)){
                            if(!"0".equals(totalNum) && !"0".equals(valueNum) && !StringHelper.isNullOrEmpty(serial_recode)){
                                //0、明细序列号|1、收款账号|2、币种(01-人民币)|3、收款户名|4、借贷标志(D-借,C-贷)|5、金额
                                //6、附言|7、交易日期|8、交易时间|9、交易状态|10、错误信息|11、批次号|
                                String[] content=serial_recode.split("\\|");
                                if(content.length==Integer.parseInt(new BigDecimal(Integer.parseInt(totalNum)+1).multiply(new BigDecimal(valueNum)).toString())){
                                    retAts.respCode = "0";
                                    retAts.respInfo=respInfo;
                                    retAts.reqSeqID = p_req1998.reqBatchNO;
                                    retAts.writeBeforeDetail();
                                    for(int i=1;i<Integer.parseInt(totalNum)+1;i++){
                                        RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                        tmpRetDetail.payAct = p_req1998.ownAct;
                                        tmpRetDetail.payName = "";
                                        tmpRetDetail.recName = content[3+i*Integer.parseInt(valueNum)].trim();
                                        tmpRetDetail.recAct =content[1+i*Integer.parseInt(valueNum)].trim();
                                        tmpRetDetail.payAmount = "";
                                        tmpRetDetail.curType = convertCurToATS(content[2+i*Integer.parseInt(valueNum)].trim());
                                        tmpRetDetail.result = respCode+"+"+content[9+i*Integer.parseInt(valueNum)].trim();
                                        tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                        tmpRetDetail.postScript = content[6+i*Integer.parseInt(valueNum)].trim();//批内流水号
                                        tmpRetDetail.usage =content[6+i*Integer.parseInt(valueNum)].trim();
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                }else {
                                    retAts.respCode ="-1";
                                    retAts.respInfo = "返回数据"+serial_recode+"异常";
                                }
                            }else {
                                retAts.respCode ="-1";
                                retAts.respInfo = respInfo+"："+errorInfo;
                            }
                        }else if("1".equals(fileFlag)){
                            String fileName=xmlSbReader.getFirstText("/ap/body/file_name");//文件名
                            if(!StringHelper.isNullOrEmpty(totalNum) && !"0".equals(valueNum) && !StringHelper.isNullOrEmpty(fileName)){
                                //下载代发结果文件
                            	StringBuilder smbSb = new StringBuilder();
                                SmbFileUtil.smbDownload(trimEndFileSp(FGBiz.dspCenter.dspSet.dataDirPath+"/QLB01")+File.separator, bankFront.bkTransFolder, fileName,smbSb);
                                WriteBankLogLn("下载代发结果文件"+fileName+"成功，开始处理");
                                //处理代发结果文件
                                File fileTrans=new File(trimEndFileSp(FGBiz.dspCenter.dspSet.dataDirPath+"/QLB01")+File.separator+fileName);
                                if(fileTrans.exists()){
                                    WriteBankLogLn(fileTrans.getName()+"文件存在，开始获取代发结果数据");
                                    InputStreamReader isr = new InputStreamReader(new FileInputStream(fileTrans.getPath()), getCharset());
                                    BufferedReader reader = new BufferedReader(isr);
                                    String readLine ="";
                                    int i=1;
                                    retAts.respCode = "0";
                                    retAts.reqSeqID = p_req1998.reqBatchNO;
                                    retAts.writeBeforeDetail();
                                    while ((readLine=reader.readLine())!=null){
                                        if(i==1){
                                            i++;
                                            continue;
                                        }
                                        i++;
                                        String[] content = readLine.split("\\|");
                                        if(content.length>1){
                                            //0、明细序列号|1、账号|2、币种(01-人民币)|3、户名|4、借贷标志(D-借,C-贷)|5、金额
                                            //6、附言|7、交易日期|8、交易时间|9、交易状态|10、错误信息|11、批次号|
                                            RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                            tmpRetDetail.payAct = p_req1998.ownAct;
                                            tmpRetDetail.payName = "";
                                            tmpRetDetail.recName = content[3];
                                            tmpRetDetail.recAct =content[1];
                                            tmpRetDetail.payAmount = content[5];
                                            tmpRetDetail.curType = convertCurToATS(content[4]);
                                            tmpRetDetail.result = respCode+"+"+content[9];
                                            tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                            tmpRetDetail.postScript = content[6];//批内流水号
                                            tmpRetDetail.usage =content[6];
                                            retAts.writeRetDetail(tmpRetDetail);
                                        }
                                    }
                                    if(FileHelper.deleteFileIfExists(fileTrans.getPath())){
                                        WriteBankLogLn("删除临时代发结果文件"+fileTrans.getName()+"成功");
                                    }
                                }
                            }
                        }
                    }else {
                        retAts.respCode = "-1";
                        retAts.respInfo = respInfo+"："+errorInfo;
                    }
                }else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            }else {
                retAts.respCode = "-1";
                retAts.respInfo = bankResult[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        }finally {
            conn.close();
        }
        if ("-1".equals(retAts.respCode) && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1998.reqBatchNO;
        }
        if ("-1".equals(retAts.respCode)) {
            retAts.writeBeforeDetail();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }
}
